<template>
  <section>
    <el-row>
      <el-col :span="6">
        <!--查询-->
        <div class="grid-content bg-purple">
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span style="line-height: 36px;">数据库</span>
              <el-button style="float: right;" type="text"><i class="fa fa-refresh" @click="refresh"></i>
              </el-button>
            </div>
            <div>
              <el-select v-model="dbsForm.hive_database_name" placeholder="请选择" @change="handleDBChange">
                <el-option v-for="item in tenant_hive" :label="item.hive_database_name"
                           :value="item.hive_database_name">
                </el-option>
              </el-select>
              <el-input v-model="filterText" placeholder="请输入表名"></el-input>

              <el-tree :data="tableList"
                       :props="defaultProps"
                       :filter-node-method="filterNode"
                       @node-click="handleNodeClick"
                       ref="tree"></el-tree>
            </div>
          </el-card>
        </div>
      </el-col>
      <el-col :span="18">
        <div class="grid-content bg-purple-light">
          <!--工作区-->
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span style="line-height: 36px;">编辑</span>
            </div>
            <div>
              <el-tabs v-model="workTabsName" type="card" closable @tab-remove="removeTab"
                       @tab-click="handleTabsChange">
                <el-tab-pane v-for="(item, index) in workTabs" :label="item.title" :name="item.name">
                  <el-form>
                    <el-form-item prop="sql">
                      <el-input
                          type="textarea"
                          :autosize="{ minRows: 3, maxRows: 6}"
                          placeholder="请输入 sql"
                          v-model="item.content">
                      </el-input>
                    </el-form-item>
                  </el-form>
                </el-tab-pane>
              </el-tabs>
            </div>
            <div class=" bottom clearfix">
              <el-button type="success" @click="runSql" :disabled="isRun">运行</el-button>
              <el-button type="primary" @click="explain" :disabled="isRun">解释</el-button>
              <el-button type="primary" @click="openFornToSave">保存</el-button>
              <el-button type="primary" @click="toPage(64)">已保存SQL</el-button>
              <el-button type="primary" @click="toPage(65)">历史</el-button>
              <el-button type="success" @click="addTab()">新工作区</el-button>
            </div>
          </el-card>
          <!--结果-->
          <el-card class="box-card">
            <div slot="header" class="clearfix">
              <span style="line-height: 36px;">结果</span>
              <!--<el-button style="float: right;" icon="upload2" type="text"></el-button>-->
            </div>
            <div class="text item">

              <el-tabs v-model="resultLogs" type="card" @tab-click="">
                <el-tab-pane label="结果" name="res">
                  <el-table
                      v-if="'object' == typeof tableData"
                      :data="tableData"
                      border
                      height='500'
                      style="width: 100%">
                    <el-table-column v-for="item in tableHeader"
                                     :prop="item.replace(/\./, '_')"
                                     :label="item">
                    </el-table-column>
                  </el-table>
                  <el-row style="text-align: center;">
                    <el-col :span="24">
                      <el-button
                          type="text"
                          v-if="'object' == typeof tableData"
                          @click="getMoreRes">加载更多</el-button>
                    </el-col>
                  </el-row>
                  <div v-if="'string' == typeof tableData">{{tableData}}</div>
                </el-tab-pane>
                <el-tab-pane label="日志" name="log">
                  <pre  class="pre" >{{queryLog}}</pre>
                </el-tab-pane>
              </el-tabs>
            </div>
          </el-card>
        </div>
      </el-col>
    </el-row>
    <!--保存界面-->
    <el-dialog :title="formTitle" v-model="dialogFormVisible">
      <div class="form-warn">
        <el-form :model="workTabsForm" :rules="editWorkTabsFormRules" ref="workTabsForm">
          <el-form-item label="标题" prop="title" :label-width="formLabelWidth">
            <el-input style="width:217px;" v-model="workTabsForm.title" auto-complete="off"></el-input>
            <span class="zhHelpTips">{{workTabsForm.zhHelpTips}}</span>
          </el-form-item>
        </el-form>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click.native="dialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click.native="saveSubmit" :loading="editLoading">{{btnEditText}}</el-button>
      </div>
    </el-dialog>
  </section>
</template>
<script>
  import util from '../../common/util'
  import NProgress from 'nprogress'
  import dao from '../../common/dao'
  import C from '../../common/cfg'
  import {mapGetters} from 'vuex'
  export default {
    watch: {
      filterText(val) {
        //this.$refs.tree.filter(val);
        let hive_database_name = this.dbsForm.hive_database_name;
        this.filterText = val;
        dao.getTableAndColumnsByName({hive_database_name, table: val}).then(this.updateTree)
      }
    },
    components: {},
    computed: {
      ...mapGetters([
        'getPgge6Sql'
      ])
    },
    data() {
      return {
        workAreas: [],
        tenant_hive: [],
        tabIndex: -1,
        dbsForm: {
          tenant_hive_id: "",
          hive_database_name: "",
          table: ""
        },
        filterText: '',
        workTabs: [],
        activeName: '',
        resultLogs: 'res',
        activeNames: [""],
        tableList: [{
          table: '',
          columns: []
        }],
        tableDataIndex: 1,
        defaultProps: {
          children: 'columns',
          label: 'label'
        },
        workTabsName: "0",
        workTabsForm: {
          title: "",
          content: "",
          zhHelpTips: ""
        },
        formLabelWidth: '100px',
        editWorkTabsFormRules: {
          title: [{
            required: true,
            message: '请输入标题',
            trigger: 'blur'
          }]
        },
        btnEditText: '保 存',
        formTitle: '保存',
        editLoading: false,
        dialogFormVisible: false,
        tableHeader: ["ID"],
        tableData: [],
        isRun: false,
        queryLog: "",
      }
    },
    methods: {
      /**
       * 增加SQL查询工作区
       */
      getWorkObj(){
        return {
          id: '',//后台sql id
          name: `${++this.tabIndex}`, //工作区名字
          title: `工作区${this.tabIndex + 1}`,//工作区标题
          content: '',//select * from default.yyt
          tableHeader: ['ID'],
          result: [],
          status: '',
          explanation: '',
          log: '',
        }
      },
      toPage(p) {
        let query = {};
        if (p == 64) {
          let hive_database_name = this.dbsForm.hive_database_name;
          query = {
            hive_database_name: hive_database_name
          }
        }
        this.$router.push({path: `/page${p}`, query});
      },
      /*保存*/
      saveSubmit() {
        this.$refs.workTabsForm.validate(valid => {
          if (valid) {
            //获取当前工作区
            let index = this.workTabsName;
            let workTab = this.workTabs[index];
            this.workTabsForm.content = workTab.content;
            let sql_name = this.workTabsForm.title;
            let sql_content = this.workTabsForm.content;
            this.btnEditText = '保存中';
            this.editLoading = true;
            dao.addQuerySql({sql_name, sql_content}).then(res => {
              if (res.FX.err) {
                this.editLoading = false;
                this.dialogFormVisible = false;
                this.btnEditText = '保 存';
                return false;
              }
              this.editLoading = false;
              this.dialogFormVisible = false;
              this.btnEditText = '保 存';
              this.$message({
                type: 'success',
                message: '保存成功!'
              });

            })
          }
        })
      },
      pageInit() {
        this.addTab();
        this.addTab();
        this.addTab();

        if (!this.getPgge6Sql.data_hive_sql_id) return false;
        let query = this.getPgge6Sql || {};
        let sql_content = query.sql_content;
        let sqlTitle = query.sql_name;
        let dbName = query.hive_database_name;
        if (sql_content != null && sql_content != "" && sql_content != "undefined") {
          let tabName = ++this.tabIndex + "";
          let obj = this.getWorkObj();
          obj.id = query.data_hive_sql_id;
          obj.title = sqlTitle;
          obj.name = tabName;
          obj.content = sql_content;
          this.workTabs.push(obj);
          this.workTabsName = tabName;
        }
      },
      getTableData() {
      },

      getHiveList() {
        dao.getHiveList({}).then(res => {
          if (!res.body || res.body.retCode != '200') {
            util.apiMsg(res);
            return false;
          }
          this.tenant_hive = res.body.tenant_hive;
          if (this.dbsForm.tenant_hive_id == '') {
            this.dbsForm.hive_database_name = (this.tenant_hive[0] || {}).hive_database_name || ''
          }
          //this.getTablesList();
        })
      },
      getTablesList() {
        let hive_database_names = [];
        if (this.dbsForm.tenant_hive_id == '') {
          hive_database_names = this.tenant_hive.map(item => {
            return item.hive_database_name
          });
        } else {
          for (let item of this.tenant_hive) {
            if (item.tenant_hive_id == this.dbsForm.tenant_hive_id) {
              hive_database_names.push(item.hive_database_name);
              break;
            }
          }
        }

        dao.getTablesList({hive_database_names}).then(res => {
          if (!res.body || res.body.retCode != '200') {
            util.apiMsg(res);
            return false;
          }
          let tableList = res.body.tenant_hive || [];
          tableList.map(item => {
            item.label = item.table;
            item.columns || (item.columns = []);
            item.columns.map(one => {
              one.label = `${one.name} -- ${one.type}`;
            })
          });
          this.tableList = tableList;
        })
      },
      updateTree(res){
        if (!res.body || res.body.retCode != '200') {
          util.apiMsg(res);
          return false;
        }
        let tableList = res.body.tables || [];
        tableList.map(item => {
          item.label = item.table;
          item.columns || (item.columns = []);
          item.columns.map(one => {
            one.label = `${one.column_name}${C.CONNECTOR}${one.type_name}`;
          })
        });
        this.tableList = tableList;
      },
      getTableAndColumnsByName() {
        let hive_database_name = this.dbsForm.hive_database_name;
        this.filterText = '';
        dao.getTableAndColumnsByName({hive_database_name, table: ''}).then(this.updateTree)
      },
      /*刷新*/
      refresh(){
        this.getTableAndColumnsByName();
      },
      handleTabsChange() {
        this.synWork();
      },
      handleDBChange(val) {
        for (let item of this.tenant_hive) {
          if (item.hive_database_name == val) {
            this.dbsForm.hive_database_name = item.hive_database_name;
            break;
          }
        }
        this.getTableAndColumnsByName();
      },
      handleNodeClick() {
      },
      filterNode(value, data) {
        if (!value) return true;
        return data.label.indexOf(value) !== -1;
      },
      /**
       * 获取当前工作区的SQL
       */
      checkSql() {
        let tab = {};
        for (let item of this.workTabs) {
          if (item.name == this.workTabsName) {
            tab = item;
            break;
          }
        }
        if (tab.content == '') this.$message('请输入sql');
        return tab
      },
      async addQuerySql(content) {
        let sql_content = content;
        let res = await dao.addQuerySql({
          sql_content
        });
        if (!res.body || res.body.retCode != '200') {
          util.apiMsg(res);
        }
        return res
      },
      /**
       * 运行按钮点击事件
       */
      async runSql() {

        this.queryLog = "";
        this.tableHeader = ["ID"];
        this.tableData = [];

        //获取tab内容
        let tab = this.checkSql();
        if (tab.content == '') return false;
        //判断是否add
        let confirm = await this.$confirm('此操作将将执行此sql, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(res => {
          return res
        }, res => {
          this.$message({
            type: 'info',
            message: '已取消执行'
          });
          return res
        });
        if (confirm != 'confirm') return false;
        const sql_content = tab.content;
        const name = tab.name;
        tab.id = '';
        tab.result = [];
        tab.log = '';
        tab.status = '';
        this.isRun = true;
        this.getRunQuerySql({name, sql_content});
      },
      /**
       * 运行SQL 请求
       */
      getRunQuerySql(e){
        let tab = this.getTab({name: e.name});
        if (!tab) {
          //this.isRun = false;
          return false
        }
        if (tab.status) {
          this.resultLogs = "res";
          this.getQueryResultHttp(tab);
        } else {
          this.resultLogs = "log"; //切换结果选项卡
          let arg = e || {queryId: this.queryId};
          dao.runQuerySql(arg).then(res => {
            if (res.FX.err) {
              this.isRun = false;
              return false
            };
            let body = res.body || {};
            let name = res.body.name || '';
            let tab = this.getTab({name});
            if (!tab) {
              this.isRun = false;
              return false
            }
            tab.id = body.queryId || '';//保存执行sql的运行ID
            tab.status = body.status || 0;//保存SQL语句运行的状态 0运行中 1完成
            tab.log += body.log || '';
            this.synWork();
            let _this = this;
            setTimeout(()=>{
              _this.getRunQuerySql({name, queryId: body.queryId})
            }, 2000);
          })
        }
      },
      getMoreRes(){
          this.getQueryResultHttp(this.getTab({name:this.workTabsName}));
      },
      /**
       * SQL查询结果 请求
       */
      getQueryResultHttp(obj){
        if(!obj.id) {
          this.isRun = false;
          return false;
        }
        dao.getQueryResult({"queryId": obj.id, offset: obj.result.length || 0}).then((response) => {
          if(response.FX.err) return false;
          let body = response.body || {};
          let header = body.columns || [];
          if(header.length==0) {
            this.$message("没有数据");
            return false
          }
          let result = body.result || [];
          let tab = this.getTab({id: body.queryId});
          tab.tableHeader = header;
          result.map(item => {
            let hang = {};
            for (let key in item) {
              let newKey = key.replace(/\./, '_');
              hang[newKey] = item[key];
            }
            tab.result.push(hang);
          });
          this.synWork();
        })
      },
      /**
       * 获取工作区
       */
      getTab(obj){
        obj || (obj = {});
        let val = obj.id, key = 'id', retTab;
        if (!val) val = obj.name, key = 'name';
        if (!val) return false;
        for (let one of this.workTabs) {
          if (one[key] == val) {
            retTab = one;
            break;
          }
        }
        return retTab;
      },
      /**
       * 根据当前选择工作区。获取相应的数据
       * */
      synWork(){
        let tab = this.getTab({name: this.workTabsName});
        if (!tab) return false;
        tab = JSON.parse(JSON.stringify(tab));
        this.queryLog = tab.log;
        this.tableHeader = tab.tableHeader;
        this.tableHeader.push('');
        this.tableData = tab.result;
        this.isRun = tab.status == '0' ? true : false;
        let _this = this;
        setTimeout(()=>{
          _this.tableHeader.pop();
        }, 200);
      },
      /**
       * 解释SQL 请求
       **/
      explain(){
        let tab = this.checkSql();
        if (tab.content == '') return false;
        let hive_sql = tab.content;
        let name = tab.name;
        dao.getExplainSql({name, hive_sql}).then(res => {
          if (res.FX.err) return false;
          let tab = this.getTab({name: res.body.name});
          if (!tab) return false;
          tab.log = res.body.qryLog;
          tab.result = res.body.explain_sql;
          this.synWork();
        })
      },
      /**
       * 保存SQL查询语句
       */
      openFornToSave(){
        let tab = this.checkSql();
        if (tab.content == '') return false;
        this.workTabsForm.title = '';
        this.dialogFormVisible = true;

      },
      /**
       * 添加工作区
       * */
      addTab(){
        this.workTabs.push(this.getWorkObj());
      },
      /* 关闭SQL查询工作区 */
      removeTab(name){
        for (let i in this.workTabs) {
          let item = this.workTabs[i];
          if (item.name == name) {
            this.workTabs.splice(i, 1);
            break;
          }
        }
      }
    },
    mounted() {

      this.pageInit();
      this.getHiveList();

    }
  }
</script>
<style scoped>
  .box-card {
    margin-bottom: 20px;
  }
  .pre {
    white-space: pre-wrap;
    word-wrap: break-word;
  }
  .bg-purple-light {
    padding-left: 20px;
  }
</style>
